import { SessionGuard } from '@/guard/session.guard';
import { ResponseBody, ResponseCode } from '@/utils/ResponseCode';
import {
  Body,
  Controller,
  Delete,
  Get,
  HttpException,
  HttpStatus,
  Param,
  Post,
  Put,
  Query,
  Req,
  Session,
  UseGuards,
} from '@nestjs/common';
import {
  GetTagsRequest,
  TagCreateRequest,
  TagUpdateRequest,
} from './dto/request.dto';
import { TagService } from './tag.service';
import { Tag as TagEntity } from '@/entity/Tag';
import { UserService } from '../user/user.service';
import { SessionType } from '@/types';
import { Request as HttpRequest } from 'express';

@UseGuards(SessionGuard)
@Controller('tag')
export class TagController {
  constructor(
    private readonly tagService: TagService,
    private readonly userService: UserService,
  ) {}

  @Post('')
  async createTag(
    @Body() requestBody: TagCreateRequest,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    const { name, coverUrl } = requestBody;
    const existTag = await this.tagService.findOneBy({ name });
    if (existTag) {
      return new ResponseBody({
        code: ResponseCode.Fail,
        message: '标签名称已经存在',
      });
    }
    try {
      const tagEntity = await this.tagService.create({ name, coverUrl });
      return new ResponseBody<number>({
        message: '标签创建成功',
        data: tagEntity.id,
      });
    } catch (error) {
      throw new HttpException(
        {
          message: error,
          code: ResponseCode.Fail,
          data: null,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @Delete(':id')
  async deleteTagById(
    @Param('id') id: number,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    try {
      await this.tagService.delete({ id });
      return new ResponseBody<TagEntity>('删除标签成功');
    } catch (error) {
      console.log(error);
      throw new HttpException(
        {
          message: error,
          code: ResponseCode.Fail,
          data: null,
        },
        HttpStatus.INTERNAL_SERVER_ERROR,
      );
    }
  }

  @Put(':id')
  async updateTagById(
    @Param('id') id: number,
    @Body() requestBody: TagUpdateRequest,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    const { name, coverUrl } = requestBody;
    const oldTag = await this.tagService.findOneBy({
      name,
    });
    if (oldTag && oldTag.id !== Number(id)) {
      return new ResponseBody({
        code: ResponseCode.Fail,
        message: '标签名称重复',
      });
    }
    await this.tagService.update(
      {
        id,
      },
      { name, coverUrl },
    );
    return new ResponseBody('更新标签成功');
  }

  @Get()
  async getTags(
    @Query() query: GetTagsRequest,
    @Req() request: HttpRequest,
    @Session() session: SessionType,
  ) {
    // 接口鉴权
    await this.userService.verifyPermission(request, session.username);
    const { current, pageSize, ...findWhere } = query;
    const { total, list } = await this.tagService.findAllAndCount(findWhere, {
      current,
      pageSize,
    });

    return new ResponseBody<{
      total: number;
      list: TagEntity[];
    }>({
      data: {
        total,
        list,
      },
      message: '获取标签列表',
    });
  }

  // abandoned 暂时废弃
  @Get(':id')
  async getTagById(@Param('id') id: number) {
    const tagEntity = await this.tagService.findOneBy({ id });
    return new ResponseBody<TagEntity>({
      data: tagEntity,
      message: '获取标签详情',
    });
  }
}
